package com.jtjrenren.android.taxi.driver.manger.push.cmd;

import com.jtjrenren.android.taxi.driver.Constants;
import com.library.utils.ConvertUtils;
import com.library.utils.StringUtils;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by wdl on 2016/2/27.
 * 协议基类 用于存放先关协议的通用方法和其他配置属性
 */
public class Protocl {
    public static final String FLAG_CMD = "7E"; //协议的标志位
    public static int CMD_MIN_SIZE = 15; //协议最少字节数

    public static int RESULT_SUCESS = 0;//0：成功/确认；1：失败；2：消息有误
    public static int RESULT_FAIL = 1;
    public static int RESULT_ERROR = 2;

    //0：即时召车；1：预约召车；2：车辆指派
    public static int ORDER_TYPE_JS = 0;
    public static int ORDER_TYPE_YY = 1;
    public static int ORDER_TYPE_ZP = 2;

    //上传指令
    public static final String CMD_SEND_COMMON = "0001"; //通用应答
    public static final String CMD_SEND_JQ = "0BD1"; //鉴权
    public static final String CMD_SEND_QD = "0B01"; //抢单
    public static final String CMD_SEND_JK = "0BA1"; //去接乘客
    public static final String CMD_SEND_CKSC = "0BA2"; //乘客上车
    public static final String CMD_SEND_FINSH = "0B07"; //订单完成
    public static final String CMD_SEND_CANCLE = "0B08"; //订单取消
    public static final String CMD_SEND_YYSJ = ""; //运营数据上传
    public static final String CMD_SEND_TJFY = "0BA3"; //提交费用信息
    public static final String CMD_SEND_TJFY_SPECAR = "0BB3"; //提交费用信息
    public static final String CMD_SEND_TJSPECARFY = "0BB3"; //专车驾驶员提交乘客付费或确认乘客现金支付
    public static final String CMD_SEND_HEART = "0002"; //心跳
    public static final String CMD_SEND_SXB = "0B21"; //驾驶员上下班
    public static final String CMD_SEND_LC = "0200"; //司机端位置信息上传
    //下发指令
    public static final String CMD_RESPONSE_COMMON="8001";//通用回复
    public static final String CMD_RESPONSE_XFDD="8B00";//5.3	中心下发订单任务
    public static final String CMD_RESPONSE_QDJG="8B01";//5.5	下发抢答结果信息
    public static final String CMD_RESPONSE_QJCK="8BA1";//5.8	中心下发驾驶员已确认去接乘客
    public static final String CMD_RESPONSE_QRSC="8BA2";//5.9	中心下发驾驶员已确认乘客已上车
    public static final String CMD_RESPONSE_TBQXDD="8BA3";//5.10	中心下发同步取消订单信息
    public static final String CMD_RESPONSE_QXDD="8B09";//5.13	中心取消订单
    public static final String CMD_RESPONSE_XFCF="8B19";//5.15	中心下发车费信息
    public static final String CMD_RESPONSE_CKZFXX="8B20";//5.17	中心下发乘客支付车费信息
    public static final String CMD_RESPONSE_QZXB="8B21";//5.20	中心强制驾驶员下班
    public static final String CMD_RESPONSE_OTHERLOGIN="8BC3";


    /**
     * 获取校验码
     *
     * @param bytes
     * @return
     */
    protected static byte getProtoclCheckCode(byte[] bytes) {
        byte result = bytes[0];
        for (int i = 1; i < bytes.length; i++) {
            result ^= bytes[i];
        }
        return result;
    }


    /**
     * 将字符串填充0
     *
     * @param valueStr
     * @param length   字符串需要达到的长度
     * @param isRight  在字符串的前边或者后边补零 true为在后边补零
     */
    protected static String fillingZero(String valueStr, int length, boolean isRight) {
        int size = valueStr.length();
        if (size < length) {
            int dis = length - size;
            String tempZero = "";
            for (int i = 0; i < dis; i++)
                tempZero += "0";
            if (isRight)
                valueStr = valueStr + tempZero;
            else valueStr = tempZero + valueStr;
        }
        return valueStr;
    }

    /**
     * 协议转义
     *
     * @param protocolBody
     * @return
     */
    protected static String getTransferredProtocl(String protocolBody) {
        int i = 0;
        int length = protocolBody.length();
        int start, end;
        String tmp;
        StringBuilder sb = new StringBuilder();
        while (i < length) {
            start = i;
            end = i + 2;
            if (end > length - 1)
                tmp = protocolBody.substring(start);
            else
                tmp = protocolBody.substring(start, end);
            if ("7d".equalsIgnoreCase(tmp)) {
                sb.append("7d01");
            } else if ("7e".equalsIgnoreCase(tmp)) {
                sb.append("7d02");
            } else {
                sb.append(tmp);
            }
            i += 2;
        }
        return sb.toString();
    }

    /**
     * 获取接收到的协议进行转义
     *
     * @param protoclStr
     * @return
     */
    protected static String getTransReceiveProtocl(String protoclStr) {
        return protoclStr.replaceAll("7d02", "7e").replaceAll("7D02", "7e")
                .replaceAll("7d01", "7d").replaceAll("7D01", "7d");
    }

    protected static String getTransReceiveProtocl2(String protoclStr) {
        StringBuilder sb = new StringBuilder();
        int length = protoclStr.length();
        int i=0;
        int start, end;
        String tmp;
        while (i < length) {
            start = i;
            end = i + 2;
            if (end > length - 1)
                tmp = protoclStr.substring(start);
            else
                tmp = protoclStr.substring(start, end);
            sb.append(tmp).append(" ");
            i += 2;
        }
        return sb.toString().replaceAll("7d 02", "7e").replaceAll("7D 02", "7e")
                .replaceAll("7d 01", "7d").replaceAll("7D 01", "7d").replaceAll(" ","");
    }


    protected static int hexIntStrToInt(String hexNum) {
        return Integer.parseInt(hexNum, 16);
    }

    protected static String intToHexInt(int num) {
        return Integer.toHexString(num);
    }


    /**
     * 将数字的电召单号 转换为16进制的电召单号
     *
     * @param orderSerial
     * @return
     */
    protected static String getOrderSerialNo(String orderSerial) {
        return ConvertUtils.bytes2hex(ConvertUtils.intToByte4(Integer.parseInt(orderSerial)));
    }

    /**
     * 将协议返回的电召单号转换为int型的整数
     *
     * @param orderSerialCmdStr
     * @return
     */
    protected static String parseOrderSerialNo(String orderSerialCmdStr) {
        return Integer.parseInt(orderSerialCmdStr, 16) + "";
    }

    /**
     * 将经度或纬度转换为UINT32 转换成16进制字符串
     *
     * @param latOrlng
     * @return
     */
    public static String latLngToUINT32Hex(String latOrlng) {
        int latOrlngInt = (int) (Double.parseDouble(latOrlng) * 600000);
        byte[] bytes = ConvertUtils.intToByte4(latOrlngInt);
        return ConvertUtils.bytes2hex(bytes);
    }

    public static String uint32ToLatLng(String latLngCmd) {
        double latlng = (double) (Integer.parseInt(latLngCmd, 16)) / 600000;
        return String.valueOf(latlng);
    }

    /**
     * GBK编码，采用’\0’终结符，若无数据，则放一个0x00终结符
     *
     * @param strValue
     */
    public static String getString(String strValue) {
        String result = "00";
        if (!StringUtils.isEmpty(strValue)) {
            try {
                byte[] temp = strValue.getBytes("gbk");
                result = ConvertUtils.bytes2hex(temp) + result;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 将通过gbk编码获取的协议中的string类型转换出来
     *
     * @param cmdStringValue
     * @return
     */
    public static String cmdStringstr2String(String cmdStringValue) {
        String result = null;
        try {
            result = new String(ConvertUtils.HexStrToByte(cmdStringValue), "GBK");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 截取以00结尾的字符串
     *
     * @param str
     */
    public static List<String> end00StringToArray(String str) {
        String s, temp = "";
        List<String> strArray = new ArrayList<String>();
        for (int i = 0; i < str.length() / 2; i++) {
            s = str.substring(i * 2, i * 2 + 2);
            if (s.equals("00")) {
                strArray.add(temp);
                temp = "";
            } else {
                temp += s;
            }
        }
        return strArray;
    }

    /**
     * 获取司机手机号在cmd的字符串
     *
     * @param phone
     * @return
     */
    public static String getDriverPhoneCmd(String phone) {
        return fillingZero(ConvertUtils.bytes2hex(ConvertUtils.str2Bcd(phone)), 12, false);
    }

    /**
     * 将cmd中的司机手机号解析出来
     *
     * @param phoneCmd
     * @return
     */
    public static String parseDriverPhoneCmd(String phoneCmd) {
        return ConvertUtils.bcd2Str(ConvertUtils.HexStrToByte(phoneCmd));
    }

    /**
     * 对于消息体长度的封装
     *
     * @param length
     * @return
     */
    protected static String getContentLen(int length) {
        return fillingZero(intToHexInt(length), 4, false);
    }


    /**
     * 获取流水号的封装
     *
     * @param serno
     */
    protected static String getSerCmd(int serno) {
        return fillingZero(intToHexInt(serno), 4, false);
    }

    /**
     * 获取车定位信息当中的车的状态封装
     * @param isGps
     * @param carStatus
     * @return
     */
    protected static String getCarLocStatusCmd(boolean isGps, int carStatus) {
        String state = "00000001";
        switch (carStatus) {
            case Constants.STATUS_CAR_KC://空车
                state = "00000001";// 空车未卫星定位1
                if (isGps)
                    state = "00000000";// 空车已卫星定位0
                break;
            case Constants.STATUS_CAR_KTZ://空转重
                state = "00000221";// 空转重未卫星定位1
                if (isGps)
                    state = "00000220";// 空转重已卫星定位0
                break;
            case Constants.STATUS_CAR_ZC://重车
                state = "00000201";// 重车未卫星定位1
                if (isGps)
                    state = "00000200";// 重车已卫星定位0
                break;
            case Constants.STATUS_CAR_ZTK://重转空
                state = "00000041";// 重转空未卫星定位1
                if (isGps)
                    state = "00000240";// 重转空已卫星定位0
                break;
        }
        return state;
    }
}
